import time
t1=time.perf_counter()
import asyncio
from metagpt.actions.action import Action
from metagpt.actions import UserRequirement
from metagpt.logs import logger
from metagpt.roles import Role
from metagpt.schema import Message
from metagpt.team import Team
from metagpt.const import MESSAGE_ROUTE_TO_ALL
# 在新建的config文件夹的config2.yaml中配置OPENAI_API_KEY

start_time=time.perf_counter()
plan_begin=time.perf_counter()
class PlanAction(Action):
    """
    构思Agent的撰写大纲Action。
    """
    name: str = "Plan"
    PROMPT_TEMPLATE: str = """
    你是一位文章创意的专家。
    按照{topic}，你需要准备文章的一个详细的大纲，按照文章类型可以适当增添内容到大纲中。
    你需要构思12个主要章节，章节内容要详细，第13章为感悟，章节小标题以一种吸引人的方式命名。
    你的任务是根据用户提供的要求，提供适合读者阅读的、专业的、有见地的文章内容创意。
    1.文章结构清晰，富有想象力，具有创新性，主题明确有深度，吸引读者阅读。
      2.文章语言表达与风格同样重要，文笔流畅、具有独特的语言风格以及恰当的修辞。
      3.文章有一定的教育意义，遵守道德和法律准则。
      4.构思的文章章节应为12个和一个感悟章节。
      5.文章鲜明，恰当的修辞和风格、张力与节奏以及有意外与惊喜。
      6.文章能引起读者情感共鸣，注意其在创意、语言描述等方面的协调性。
      大纲以Markdown形式输出。
    """

    async def run(self, topic: str):
        """
        根据用户提供的要求撰写一个详细的大纲，划分12个主体章节和1个感悟章节。
        """
        prompt = self.PROMPT_TEMPLATE.format(topic=topic)
        plan_result = await self._aask(prompt)
        return plan_result

class Planner(Role):
    """
    构思者。
    """
    name: str = "A"
    profile: str = "Planner"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._watch([UserRequirement])
        self.set_actions([PlanAction])

    async def _act(self) -> Message:
        """
        构思者动作：根据用户要求撰写详细的大纲包括主题，结构以及划分12个主体章节和1个感悟章节。
        """
        logger.info(f"{self._setting}: ready to {self.rc.todo}")
        todo = self.rc.todo
        msg = self.get_memories()  # 获取所有对话记忆
        planing = await PlanAction().run(topic=input("用户要求"))
        plan_result = Message(content=planing, role=self.profile, cause_by=type(todo))
        return plan_result
    
planner = Planner()
result1 = await planner._act()
plan_result=result1.content
print(plan_result)
plan_final=time.perf_counter()
plan_time=plan_final-plan_begin

write_begin=time.perf_counter()
chapter_number=1
story_content=""
while chapter_number < 14:
    class WriteAction(Action):
        """
        写作Agent的编写文章Action。
        """
        name: str = "Write"
        PROMPT_TEMPLATE: str = """
            你是一位文章章节编写专家，你编写的章节内容有创新性，特别适合阅读。
            1.根据{plan_result}的大纲内容，可以按照需求适当添加细节，扩充不少于800个汉字的第{chapter_number}个章节内容。
            2.第{chapter_number}个章节段落内容不能重复，应有恰当的修辞以让字数不少于800个汉字。
            3.第二章根据{story_content}的第一章章节发展和划分的第二章续写，以此类推，直至第十二章。
            4.第一至十二章不用写感悟。
            5.根据{plan_result}扩充第十三章且字数不少于500字。
            6.每一章节要有标题和标注第几章，第一章最前面要先输出文章标题，以Markdown形式输出
            7.只需要输出第{chapter_number}章节内容chapter_content，不需要输出其他章节。
            """
        async def run(self,chapter_number:int,plan_result:str,story_content:str) -> str:
            """
            按照章节和大纲编写文章，需要输出文章标题并且居中显示，章节标题和章节内容，以Markdown形式输出。
            """
            prompt = self.PROMPT_TEMPLATE.format(chapter_number=chapter_number,plan_result=plan_result,story_content=story_content)
            chapter_content = await self._aask(prompt)
            return chapter_content
    
    class Writer(Role):
        """
        写作角色。
        """
        name: str = "B"
        profile: str = "Writer"

        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            self.set_actions([WriteAction])
            self._watch([PlanAction,WriteAction])

        async def _act(self) -> Message:
            """
            写作动作：1.根据{plan_result}的大纲内容，可以按照需求适当添加细节，扩充不少于800个汉字的第{chapter_number}个章节内容。
            2.第{chapter_number}个章节段落内容不能重复，字数不少于800个汉字。
            3.第二章根据{story_content}的第一章章节发展和{plan_result}划分的第二章续写，以此类推，直至第十二章。
            4.第一至十二章不用写感悟。
            5.根据{plan_result}扩充第十三章且字数不少于500字。
            6.整个文章章节按照顺序排列,需要输出文章标题并且居中显示，章节要有标题和标注第几章，以Markdown形式输出。
            7.只需要输出第{chapter_number}章节内容chapter_content，不需要输出其他章节。
            """
            logger.info(f"{self._setting}: ready to {self.rc.todo}")
            todo = self.rc.todo
            msg = self.get_memories()
            chapter = await WriteAction().run(chapter_number,plan_result,story_content)
            chapter_content = Message(content=chapter, role=self.profile, cause_by=type(todo))
            return chapter_content
    
    writer = Writer()
    result2 = await writer._act()
    chapter_content=result2.content
    story_content+=chapter_content + "\n"
    chapter_number=chapter_number + 1
print(story_content)
write_final=time.perf_counter()
write_time=write_final-write_begin

score_begin=time.perf_counter()
class ScoreAction(Action):
    """
    打分Agent的打分文章Action。
    """
    name: str = "Score"
    PROMPT_TEMPLATE: str = """
    你是一位文章打分专家，为了让文章更符合要求，你需要对文章内容{story_content}进行打分。
      你的任务是根据对{story_content}的文章进行打分。
      1.评估文章的创意(5分)与主题(5分)，考察其创新性(5分)、主题深度(5分)以及明确性(5分)。
      2.深入分析结构构建(10分)，包括逻辑性(10分)、张力与节奏(5分)以及意外与惊喜(5分)。
      3.我们关注文章内容的丰富性(5分)，无明显的错误(10分)以及语言的准确性(5分)。
      4.语言表达与风格同样重要，文笔的流畅性(5分)、独特的语言风格(5分)以及恰当的修辞(5分)。
      5.综合考虑文章的整体印象，评估其在创意、结构、文章风格等方面的协调性(5分)，以及是否能够触动读者的心灵，留下深刻印象(5分)
      6.计算这次评分最后的总分。
      7.按照标准进行10次评分，10次总分相加，求平均值scores例如： 3并在最后一行以数字形式输出。
    """
    async def run(self,story_content:str):
        prompt = self.PROMPT_TEMPLATE.format(story_content=story_content)
        scores = await self._aask(prompt)
        return scores
    
class Scorer(Role):
    """
    打分角色。
    """
    name: str = "C"
    profile: str = "Scorer"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.set_actions([ScoreAction])
        self._watch([WriteAction,ScoreAction])

    async def _act(self) -> Message:
        """
        打分动作：根据文章内容进行10次评分，10次总分相加，求平均值scores例如：3，只需输出scores。
        """
        logger.info(f"{self._setting}: ready to {self.rc.todo}")
        todo = self.rc.todo
        msg = self.get_memories()  # 获取所有对话记忆
        sco = await ScoreAction().run(story_content)
        scores = Message(content=sco, role=self.profile, cause_by=type(todo))
        return scores

scorer = Scorer()
result3 = await scorer._act()
scores=result3.content
print(scores)
score_final=time.perf_counter()
score_time=score_final-score_begin

finally_time=time.perf_counter()
cooperation=round(((plan_time+write_time+score_time)/(finally_time-start_time))*100,2)
cost=round((len(story_content)+len(plan_result)+len(scores))*2*0.000002,2)
weight = 0.5
resource_weight = 0.1
collaboration_weight = 0.4
import re
sco=scores[-9:]
match = re.search(r'\d+', sco)
if match:
    score_value = int(match.group())
else:
    print("无法从 score_result 中提取数字")
success_rate=round((score_value * weight + cost * resource_weight + cooperation * collaboration_weight),2)
file = open(r"..\MetaGpt\file3.txt", "w", encoding="utf-8")
file.write(story_content)
file.close()
file = open(r"..\MetaGpt\score3.txt", "w", encoding="utf-8")
file.write(scores)
file.close()
print("耗费时间："+str(finally_time-t1))
print("协作效率："+str(cooperation)+"%")
print("花费："+str(cost))
print("综合评分："+str(success_rate)+"%")
file = open(r"..\MetaGpt\result3.txt", "w", encoding="utf-8")
file.write("耗费时间："+str(finally_time-t1) +'\n'+ "协作效率："+str(cooperation)+"%" +'\n'+ "花费："+str(cost) +'\n'+ "综合评分："+str(success_rate)+"%")
file.close()